package wisp.game;

//JFC
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

//WISP objects
import wisp.dataObjects.Statistics;
import wisp.dataObjects.WispCharacter;

//WISP GUI
import wisp.gui.SkillBar;
import wisp.gui.SkillWindow;

//GTGE
import com.golden.gamedev.object.Timer;

public class Templar extends PlayerSprite {

	
	private Timer bashTimer;
	private Timer berserkCDTimer;
	private Timer berserkCastTimer;
	private Timer berserkDurationTimer;
	
	private boolean bashOnCoolDown;
	private boolean berserkOnCoolDown;
	private boolean berserkCasting;
	private boolean berserkDuration;
	
	private int buffCounter;
	private int bashSkillLevel; //dapat may max level attained and current skill na ginagamit :X
	private int berserkSkillLevel;
	private int toughnessSkillLevel;
	
	private int bashCD = 100; //cast time
	private int berserkCD = 2000; //cast time
	
	
	
	public Templar(String name, MainGame game, BufferedImage[] images, double x, double y) {
		super(name, game, images, x, y);

		bashTimer = new Timer (bashCD);
		bashTimer.setActive(false);
		
		berserkCDTimer = new Timer(120000);
		berserkCDTimer.setActive(false);
		berserkCastTimer = new Timer(2000);
		berserkCastTimer.setActive(false);
		berserkDurationTimer = new Timer(30000);
		berserkDurationTimer.setActive(false);
		
		berserkOnCoolDown = false;
		berserkCasting = false;
		berserkDuration = false;
		
		
		bashSkillLevel = 0; //pakinote! dapat zero toh pag handa na si skill window!!
		berserkSkillLevel = 0;
		toughnessSkillLevel = 0;
		buffCounter = 0;
		
		//this.setSkillUpgradePoints(30);
	}
	
	 //SPRITE FRAME INFO
    //
    //
    public int[] getUpImages() {
        return new int[] {18,19,20};
    }
    public int[] getDownImages(){
        return new int[] {0,1,2};
    }
    public int[] getLeftImages(){
        return new int[] {6,7,8};
    }
    public int[] getRightImages(){
        return new int[] {12,13,14};
    }
    
    //ADDED//
    public int[] getUpFlinch(){
    	return new int[]{21,22,23};
    }
    
    public int[] getDownFlinch(){
    	return new int[]{15,16,17};
    }
    
    public int[] getLeftFlinch(){
    	return new int[]{9,10,11};
    }
    
    public int[] getRightFlinch(){
    	return new int[]{3,4,5};
    }

    //END ADDED//
	
    ///////////added - for buff <TEMP VALUES! UPDATE PLZ>
    public int[] getUpBuffed(){
    	return new int[]{42,43,44};
    }
    public int[] getDownBuffed(){
    	return new int[]{24,25,26}; 
    }
    public int[] getLeftBuffed(){
    	return new int[]{30,31,32};
    }
    public int[] getRightBuffed(){
    	return new int[]{36,37,38};
    }
    //////////////////////////////

	private static final long serialVersionUID = 1L;

	public void update(long elapsedTime)
	{
		//enable skills in skill bar if it's already unlocked
		if(bashSkillLevel>0){
			this.getSkillBar().btn1.setEnabled(true);
		}else
			this.getSkillBar().btn1.setEnabled(false);
		
		if(berserkSkillLevel>0){
			this.getSkillBar().btn2.setEnabled(true);
		}else
			this.getSkillBar().btn2.setEnabled(false);
		
		
		//check for buffs
		performBerserkDurationCheck(elapsedTime);
		
		// enable|disable skill buttons depending on mana lol
		super.update(elapsedTime);
	}

	
	//Bash
	public void performSkill1()
	{
		if(hasTarget()){
		
			if(this.getCurrentMP() > 0)
			{
				System.out.println ("bash daw~~~");
		
				bashTimer.setActive(true);
				bashOnCoolDown = true;
			 
				boolean attackFlag = attackIsSuccessful();
				if( attackFlag == true)
				{
					double damage = this.computeDamage(attackFlag);
					damage = damage * getBashBonusValue();
					System.out.println(this.getName() + " hits with BASH" + this.getTarget().getName() + "!");
					
					
					try
					{
						this.getGame().getParticleGroup().add(new HitSprite(this.getGame().getImages("IMAGES/Sprites/bash.png", 3, 1), getTarget().getX(), getTarget().getY()));
					}
					catch (NullPointerException e)
					{
						System.out.println (e.getMessage());
						if ( getTarget() == null)
							System.out.println ("nezie's hot!");
					}
					
					getTarget().hit(this,damage);
				}
				
				this.setCurrentMP(new Double(this.getCurrentMP() - ( this.getMaxMP() * .15)).intValue());
				
				//set skillbar button
				this.getSkillBar().btn1.setEnabled(false);
				//
			}
			else
				System.out.println("No Mana for BASH");
		}
		else
			System.out.println("BASH has no target~!");
	}
	
	private double getBashBonusValue()
	{
		double bonus;
		switch (this.bashSkillLevel)
		{
			case 1: bonus = 1.5; break;
			case 2: bonus = 1.75; break;
			case 3: bonus = 2.0; break;
			case 4: bonus = 2.25; break;
			case 5: bonus = 2.5; break;
			case 6: bonus = 2.75; break;
			case 7: bonus = 3.0; break;
			case 8: bonus = 3.25; break;
			case 9: bonus = 3.5; break;
			case 10: bonus = 4.0; break;
			default: bonus = -1;
		}
		return bonus;
	}
	
	private double getBerserkBonusValue()
	{
		double bonus;
		switch (this.berserkSkillLevel)
		{
			case 1: bonus = 0.5; break;
			case 2: bonus = 0.7; break;
			case 3: bonus = 0.9; break;
			case 4: bonus = 0.11; break;
			case 5: bonus = 0.13; break;
			case 6: bonus = 0.15; break;
			case 7: bonus = 0.17; break;
			case 8: bonus = 0.19; break;
			case 9: bonus = 0.21; break;
			case 10: bonus = 0.25; break;
			default: bonus = -1;
		}
		return bonus;
	}

	//Berserk
	public void performSkill2() 
	{
		 System.out.println ("Buff Berserk activated~~~~~~~~~~~~~~~~~~~~~~~~~");
		 berserkCDTimer.setActive(true);
		 berserkOnCoolDown = true;
		 
		 Statistics stat = this.getStatistics();
		 stat.setSpd(computeBerserkBonusSpd() + stat.getSpd());
		 stat.setAtk(computeBerserkBonusAtk() + stat.getAtk());
		 
		 berserkDurationTimer.setActive(true);
		 berserkDuration = true;
		 
		 this.setCurrentMP(new Double(this.getCurrentMP() - ( this.getMaxMP() * .5)).intValue());
		 
		 //enable buff animation
		 this.setBuffed(true);
		 this.setCurrentMP( this.getCurrentMP()-20);
		 //set skillbar button
		 this.getSkillBar().btn2.setEnabled(false);
		 //
		 
		 buffCounter ++;
	}
	
	private double computeBerserkBonusSpd()
	{
		Statistics stat = this.getStatistics();
		return (stat.getSpd() * getBerserkBonusValue());
	}

	private int computeBerserkBonusAtk()
	{
		Statistics stat = this.getStatistics();
		return (new Double(stat.getAtk() * .05).intValue());
	}
	
	@Override
	public void performSkill3() {
		// TODO Auto-generated method stub
		
	}
	

	
	private void performBashCDCheck(long elapsedTime)
	{
		if (bashTimer.action(elapsedTime) == true)
		{
		      bashTimer.setActive(false);
		      bashOnCoolDown = false;
		      
		      this.getSkillBar().btn1.setEnabled(true);
		}
		
	}
	
	private void performBerserkCDCheck(long elapsedTime)
	{
		if (berserkCDTimer.action(elapsedTime) == true)
		{
		      berserkCDTimer.setActive(false);
		      berserkOnCoolDown = false;
		      
		     
		}
	}
	
	
	private void performBerserkCastingCheck(long elapsedTime)
	{
		//if casting time wasn't interrupted and has finished
		if (berserkCastTimer.action(elapsedTime)== true)
		{
			berserkCastTimer.setActive(false); //stop timer
			if( berserkCasting = true) // nde nainterrupt
			{
				System.out.println ("Casting time finished===================");
			    performSkill2();
			}
		}
	}
	
	private void performBerserkDurationCheck(long elapsedTime)
	{
		if (berserkDurationTimer.action(elapsedTime))
		{
			berserkDurationTimer.setActive(false); 
			berserkDuration = false;
			this.getSkillBar().btn2.setEnabled(true);
			System.out.println("buff berserk removed!! @@@@@@@@@@@@@@@@@@");
			
			//remove buff animation
			this.setBuffed(false);
			//
			
			//reset the stats
			Statistics stat = this.getStatistics();
			stat.setSpd(stat.getSpd() - computeBerserkBonusSpd());
			stat.setAtk(stat.getAtk() - computeBerserkBonusAtk());
			buffCounter --;
			
		}
	}
	
	/*************** MODIFIED *****************************/
	// skill commands are mapped here, instead of the main game class
	// skill bar sends commands here~
	// 
	public void checkForSkillUse(long elapsedTime)
	{
		
		//perform checks on Skill Cooldowns, Casting Time and Duration
		performBashCDCheck(elapsedTime);
		performBerserkCDCheck(elapsedTime);
		performBerserkCastingCheck(elapsedTime);
		
	
		if (getGame().keyPressed(KeyEvent.VK_1)  || this.getSkillKeyUsed() == 1)
		{
			
			 if (getTarget() != null && bashOnCoolDown == false)
			 {
				 if (bashSkillLevel > 0)
				 {
					 performSkill1();
					 this.setSkillKeyUsed(-1);
				 }
				 else
					 System.out.println("No skill point here yet~");
			 }
			 else
			 { 
				 System.out.println ("cant use skill yet!");
				 this.setSkillKeyUsed(-1);
			 }
		}
		
		if (getGame().keyPressed(KeyEvent.VK_2)  || this.getSkillKeyUsed() == 2)
		{
			if (berserkOnCoolDown == false)
			{
				if (berserkSkillLevel > 0)
				berserkCasting = true; //start casting 
				berserkCastTimer.setActive(true); // start cooldown timer
				this.setSkillKeyUsed(-1);
				System.out.println ("Casting time started >>>>>>>>>>>>>>>>>>>>>>>>>");
			}
			else
				System.out.println("No skill point here yet~");
			    
		}
		if (getGame().keyPressed(KeyEvent.VK_3))
		{
			System.out.println ("bash daw*******");
			
			    performSkill3();
		}
	}
	
	public void checkIfLevelUp(int exp)
	{
		super.checkIfLevelUp(exp);
		//this.setStatistics(this.getLevelInfo().getNewTemplarStatistics(this.getLevel()));
	}
	
	public void configSkillbar(SkillBar s){
		this.setSkillBar(s);
		
		this.getSkillBar().btn1.setText("Bash 0");
		this.getSkillBar().btn2.setText("Brsrk 0");
		
		this.getSkillBar().btn3.setText("Tough 0");
		this.getSkillBar().btn3.setEnabled(false);
	}
	
	public void configSkillWindow(SkillWindow s){
		s.setSkill1("Bash", "Attack a target with all your might!", 0, (new Double(( this.getMaxMP() * .15)).intValue()), bashCD/1000);
		s.setSkill2("Berserk", "Unleashes your inner beast", 0, (new Double(( this.getMaxMP() * .5)).intValue()), berserkCD/1000);
		s.setSkill3("Toughness", "Strengthens your physical body (Passive)", 0, 0, 0);
		
		this.setSkillWindow(s);
	}
	
	public void increaseSkill1(){
		
		bashSkillLevel++;
		System.out.println("[PLAYER] Bash level increased to " + bashSkillLevel);
		
		this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
		
		//UPDATE skillwindow info if nescessary~
		this.getSkillWindow().sk1sLevel.setText(((Integer)bashSkillLevel).toString());
		this.getSkillWindow().sk1sCost.setText((new Double((this.getMaxMP() * .15)).toString()));
		this.getSkillBar().btn1.setText("Bash " + this.bashSkillLevel);
	}
	
	public void increaseSkill2(){
	
		berserkSkillLevel++;
		System.out.println("[PLAYER] Berserk level increased to " + berserkSkillLevel);
		
		this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
		
		//updating stuff...
		this.getSkillWindow().sk2sLevel.setText(((Integer)berserkSkillLevel).toString());
		this.getSkillBar().btn2.setText("Brsrk " + this.berserkSkillLevel);
		//this.getSkillWindow().sk1sCost.setText((new Double(this.getCurrentMP() - ( this.getMaxMP() * .15)).toString()));
		
	}
	
	public void increaseSkill3(){
		int bonusStat, bonusHP;
		
		bonusStat = 0;
		bonusHP = 0;
		
		
			toughnessSkillLevel++;
			
			switch (toughnessSkillLevel) {
			case 1: {		
				bonusStat = 2;
				bonusHP = 50;
			}break;
			case 2: {
				bonusStat = 4;
				bonusHP = 75;	
			}break;
			case 3: {
				bonusStat = 6;
				bonusHP = 100;
			}break;
			case 4: {
				bonusStat = 8;
				bonusHP = 125;
			}break;
			case 5: {
				bonusStat = 10;
				bonusHP = 150;
			}break;
			case 6: {
				bonusStat = 12;
				bonusHP = 175;
			}break;
			case 7: {
				bonusStat = 14;
				bonusHP = 200;
			}break;
			case 8: {
				bonusStat = 16;
				bonusHP = 225;
			}break;
			case 9: {
				bonusStat = 18;
				bonusHP = 250;
			}break;
			case 10: {
				bonusStat = 20;
				bonusHP = 300;
			}break;

			default:
				break;
			}
			
			//increase stats and hp~
			this.getStatistics().setStr(getStatistics().getStr() + bonusStat);
			this.getStatistics().setVit(getStatistics().getVit() + bonusStat);
			
			this.getWispcharacter().setMHP(getWispcharacter().getMHP() + bonusHP);
			this.setMaxHP(getMaxHP() + bonusHP);
			this.setCurrentHP(getCurrentHP() + bonusHP);
			
			//
			System.out.println("[PLAYER] Toughness level increased to " + toughnessSkillLevel);
			
			this.setSkillUpgradePoints(this.getSkillUpgradePoints()-1);
			
			//updating stuff...
			this.getSkillWindow().sk3sLevel.setText(((Integer)toughnessSkillLevel).toString());
			
			this.getSkillBar().btn3.setText("Tough " + this.toughnessSkillLevel);
		
	}
	
	public int get1stSkillLevel(){
		return bashSkillLevel;
	}
	public int get2ndSkillLevel(){
		return berserkSkillLevel;
	}
	public int get3rdSkillLevel(){
		return toughnessSkillLevel;
	}
	
	

}
